﻿#define _CRT_SECURE_NO_WARNINGS 1

//lambda表达式
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
//
//int main()
//{
//	int array[] = { 4,1,8,5,3,7,0,9,2,6 };
//	sort(array, array + sizeof(array) / sizeof(array[0]));
//	for (auto x : array)
//	{
//		cout << x << " ";
//	}
//	cout << endl;
//	sort(array, array + sizeof(array) / sizeof(array[0]), greater<int>());
//	for (auto x : array)
//	{
//		cout << x << " ";
//	}
//	cout << endl;
//	return 0;
//}

//struct Goods
//{
//	string _name; //名字
//	double _price; //价格
//	int _evaluate; //评价
//
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		, _price(price)
//		, _evaluate(evaluate)
//	{}
//};
//
//struct ComparePriceLess 
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//
//struct ComparePriceGreater
//{
//	bool operator()(const Goods& gl, const Goods& gr) 
//	{
//		return gl._price > gr._price;
//	}
//};


#include<vector>

//int main()
//{
//	vector<Goods> v = { {"苹果",2.1,5} ,{ "香蕉",3,4 }, {"菠萝",1.5,4 }};
//	sort(v.begin(), v.end(), ComparePriceGreater());
//
//	return 0;
//}

//[capture - list](parameters) mutable -> return-type{ statement}
//捕捉列表 参数 取消常性 返回值 函数体

//int main()
//{
//	vector<Goods> v = { {"苹果",2.1,5} ,{ "香蕉",3,4 }, {"菠萝",1.5,4 }};
//	sort(v.begin(), v.end(), 
//		[](const Goods& g1, const Goods& g2) 
//		{return g1._price < g2._price; });
//	sort(v.begin(), v.end(), [](Goods& g1, const Goods& g2)
//		{return g1._price > g2._price; });
//
//	return 0;
//}


//int main()
//{
//	//最简单的lambda表达式,该表达式没有任何意义
//	[] {};
//	//省略参数列表和返回值类型, 返回值类型由编译器自动推导为int
//	int a = 3, b = 4;
//	[=] {return a + 3; };
//
//	//省略了返回值类型, 无返回值类型
//	auto fun1 = [&](int c) {b = a + c; };
//	fun1(10);
//	cout << a << " " << b << endl;
//
//	//各部分都很完善的lambda表达式
//	auto fun2 = [=, &b](int c)->int {return b += a + c; };
//	cout << fun2(10) << endl;
//
//	//赋值捕捉x
//	int x = 10;
//	auto add_x = [x](int a)mutable {x *= 2; return a + x; };
//	cout << add_x(10) << endl;
//	return 0;
//}

//void (*PF)();
//
//int main()
//{
//	auto f1 = [] {cout << "hello world" << endl; };
//	auto f2 = [] {cout << "hello world" << endl; };
//	// 此处先不解释原因，等lambda表达式底层实现完后，大家就清楚了
//	//f1 = f2;   // 编译失败--->提示找不到operat==()
//
//	//允许使用一个lambda表达式拷贝构造一个新的副本
//	auto f3(f2);
//	f3();
//
//	//可以将lambda表达式赋值给相同类型的函数指针
//	PF = f2;
//	PF();
//	return 0;
//}

//class Rate
//{
//public:
//	Rate(double rate)
//		: _rate(rate)
//	{}
//
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//private:
//	double _rate;
//};
//
//int main()
//{
//	//函数对象
//	double rate = 0.49;
//	Rate r1(rate);
//	r1(100000, 2);
//
//	//lambda
//	auto r2 = [=](double money, int year)->double {return money * rate * year; };
//	r2(100000, 2);
//	return 0;
//}


//auto ret = func(x);

//上面func可能是什么呢?func可能是函数名?函数指针?函数对象(仿函数对象)?也有可能
//是lambda表达式?所以这些都是可调用的类型, 如此丰富的类型,可能会导致模板的效率低下,
//why? 继续往下看

//template<class F, class T>
//T useF(F f, T x)
//{
//	static int count = 0;
//	cout << "count:" << ++count << endl;
//	cout << "count:" << &count << endl;
//
//	return f(x);
//}
//
//double f(double i)
//{
//	return i / 2;
//}
//
//struct Functor
//{
//	double operator()(double d)
//	{
//		return d / 3;
//	}
//};
//
//int main()
//{
//	//函数名
//	cout << useF(f, 11.11) << endl;
//
//	//函数对象
//	cout << useF(Functor(), 11.11) << endl;
//
//	//lambda表达式
//	cout << useF([](double d) -> double {return d / 4; }, 11.11) << endl;
//
//	return 0;
//}

//#include<functional>
//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator()(int a, int b)
//	{
//		return a + b;
//	}
//};
//
//class Plus
//{
//public:
//	static int plisi(int a, int b)
//	{
//		return a + b;
//	}
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//
//int main()
//{
//	//函数名(函数指针)
//	function<int(int, int)> func1 = f;
//	cout << func1(1, 2) << endl;
//
//	//函数对象
//	function<int(int, int)> func2 = Functor();
//	cout << func2(1, 2) << endl;
//	
//	//lambda表达式
//	function<int(int, int)> func3 = [](const int a, const int b) {return a + b; };
//	cout << func3(1, 2) << endl;
//
//	//静态成员函数属于整个类, 不需要&但是建议都加上&
//	function<int(int, int)> func4 = Plus::plisi;
//	cout << func4(1, 2) << endl;
//
//	//普通成员函数需要传递this指针加上&
//	function<double(Plus, double, double)> func5 = &Plus::plusd;
//	cout << func5(Plus(), 1.1, 2.2) << endl;
//	return 0;
//}


//template<class F,class T>
//T useF(F f, T x)
//{
//	static int count = 0;
//	cout << "count:" << ++count << endl;
//	cout << "count" << &count << endl;
//	return f(x);
//}
//
//double f(double i)
//{
//	return i / 2;
//}
//
//struct Functor
//{
//	double operator()(double d) 
//	{
//		return d / 3;
//	}
//};
//int main()
//{
//	//函数名
//	function<double(double)> func1 = f;
//	cout << useF(func1, 11.11) << endl;
//
//	//函数对象
//	function<double(double)> func2 = Functor();
//	cout << useF(func2, 11.11) << endl;
//
//	//lambda表达式
//	std::function<double(double)> func3 = [](double d)->double {return d / 4; };
//	cout << useF(func3, 11.11) << endl;
//	return 0;
//}

#include<functional>

int Plus(int a, int b)
{
	return a + b;
}

class Sub
{
public:
	int sub(int a, int b)
	{
		return a - b;
	}
};

int main()
{
	////表示绑定函数plus 参数分别由调用 func1 的第一，二个参数指定
	function<int(int, int)> func1 = bind(Plus, placeholders::_1, placeholders::_2);
	//auto func1 = bind(Plus, placeholders::_1, placeholders::_2);
	cout << func1(1, 2) << endl;

	//func2的类型为 function<void(int, int, int)> 与func1类型一样
	//表示绑定函数 plus 的第一，二为： 1， 2
	auto func2 = bind(Plus, 1, 2);
	cout << func2() << endl;

	Sub s;
	//绑定成员函数
	function<int(int, int)> func3 = bind(&Sub::sub, s, placeholders::_1, placeholders::_2);

	//参数调换顺序
	function<int(int, int)> func4 = bind(&Sub::sub, s, placeholders::_2, placeholders::_1);
	
	cout << func3(1, 2) << endl;
	cout << func4(1, 2) << endl;

	return 0;
}


//单词接龙
//class Solution {
//public:
//    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
//        unordered_set<string> hash(wordList.begin(), wordList.end());
//        unordered_set<string> vis;
//
//        if (!hash.count(endWord)) return 0;
//        if (beginWord == endWord) return 1;
//
//        queue<string> q;
//        q.push(beginWord);
//        vis.insert(beginWord);
//        int ret = 1;
//        while (q.size())
//        {
//            ret++;
//            int sz = q.size();
//            while (sz--)
//            {
//                string front = q.front();
//                q.pop();
//                for (int i = 0; i < front.size(); i++)
//                {
//                    string tmp = front;
//                    for (char ch = 'a'; ch <= 'z'; ch++)
//                    {
//                        tmp[i] = ch;
//                        if (!vis.count(tmp) && hash.count(tmp))
//                        {
//                            q.push(tmp);
//                            vis.insert(tmp);
//                            if (tmp == endWord) return ret;
//                        }
//                    }
//                }
//            }
//        }
//        return 0;
//    }
//};